package org.cunamas.web.controller;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.cunamas.core.bean.ItemBean;
import org.cunamas.core.bean.LocalesBean;
import org.cunamas.core.bean.LogBean;
import org.cunamas.core.bean.MonitoreoCruzadoBean;
import org.cunamas.core.bean.ServiciosAlimentariosBean;
import org.cunamas.core.dto.Filtros;
import org.cunamas.core.service.CrossMonitoringDataService;
import org.cunamas.core.service.ReportesCunamasService;
import org.cunamas.web.util.CunamasConstants;
import org.cunamas.web.util.ExcelReader;
import org.cunamas.web.util.MessagesView;
import org.cunamas.web.util.PDFUtil;
import org.cunamas.web.util.WebUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("session")
public class CrossMonitoringController {

	@Autowired
	private ReportesCunamasService cunamasService;

	@Autowired
	private CrossMonitoringDataService crossMonitoringDataService;

	private List<SelectItem> listaProv = new ArrayList<SelectItem>();

	private List<SelectItem> listaDis = new ArrayList<SelectItem>();

	private List<SelectItem> listaDep = new ArrayList<SelectItem>();

	private List<SelectItem> listaSede = new ArrayList<SelectItem>();

	private List<SelectItem> listaComite = new ArrayList<SelectItem>();

	private List<SelectItem> listaSupervisor = new ArrayList<SelectItem>();

	private String departamento = "00";
	private String provincia = "00";
	private String distrito = "00";
	private String comite = "000";
	private String sede = "000";
	private String anio;
	private String mes;
	private Long trimestre;
	private Long formato;
	private Long supervisor;

	private String onload = "";

	private List<ServiciosAlimentariosBean> serviciosAlimentariosBeans = new ArrayList<ServiciosAlimentariosBean>();
	private List<LocalesBean> localesBeans = new ArrayList<LocalesBean>();

	ServiciosAlimentariosBean totalesServiciosAlimentariosBean = null;
	List<ServiciosAlimentariosBean> itemsServiciosAlimentariosBean = null;
	LocalesBean totalesLocalesBean = null;
	List<LocalesBean> itemsLocalesBean = null;
	
	List<ItemBean> calificacionNivelesServiciosAlimentarios = null;
	List<ItemBean> calificacionNivelesCocinaBean = null;
	List<ItemBean> calificacionNivelesAlmacenBean = null;
	List<ItemBean> calificacionNivelesMedidasSeguridadBean = null;
	List<ItemBean> calificacionNivelesDocumentacionYRegistrosBean = null;
	
	List<ItemBean> calificacionNivelesLocales = null;
	List<ItemBean> calificacionNivelesMedidasSeguridadLocalBean = null;
	List<ItemBean> calificacionNivelesImplementosBasicosBean = null;
	List<ItemBean> calificacionNivelesInstrumentosDocumentacionRegistrosBean = null;
	List<ItemBean> calificacionNivelesAparienciaActitudesConductaBean = null;

	private String messageError = null;
	private String fileName = null;
	private String nameFile = null;

	private String fileNamePDF = null;
	private String nameFilePDF = null;

	public void loadDefaultValues() {
		messageError = null;
		anio = null;
		trimestre = null;
		formato = 0L;
		supervisor = 0L;
		departamento = "00";
		provincia = "00";
		distrito = "00";
		comite = "000";
		sede = "000";

		fileName = null;
		nameFile = null;
		fileNamePDF = null;
		nameFilePDF = null;
	}

	public void generarReporte() {
		messageError = null;
		
		LogBean logBean=null;
		Filtros filtros = new Filtros();
		try {

			filtros.setAnio(anio);
			filtros.setTrimestre(trimestre);
			filtros.setCom(comite);
			filtros.setSede(sede);
			filtros.setUbigeo(getUbigeo());
			filtros.setFormato(formato); // 1: supervision CC, 2: supervision
											// AA,
			filtros.setSupervisor(supervisor);

			// Formato 1: supervision CC, 2: supervision AA,
			Long formatoComite = 0L;
			Long formatoLocal = 0L;

			if (formato != null && formato.compareTo(0L) != 0) {
				formatoComite = formato.equals(1L) ? CunamasConstants.SUPERVISION_COMITE_CC
						: CunamasConstants.SUPERVISION_COMITE_AA;
				formatoLocal = formato.equals(1L) ? CunamasConstants.SUPERVISION_LOCAL_CC
						: CunamasConstants.SUPERVISION_LOCAL_AA;
			}

			filtros.setFormato(formatoComite);
			serviciosAlimentariosBeans = cunamasService
					.retornaServiciosAlimentarios(filtros);

			filtros.setFormato(formatoLocal);
			localesBeans = cunamasService.retornaLocales(filtros);
			System.out.println("localesBeans = " + localesBeans.size());

			getServiciosAlimentariosInputs(serviciosAlimentariosBeans);
			getLocalesInputs(localesBeans);
			
			MonitoreoCruzadoBean monitoreoCruzadoBean = new MonitoreoCruzadoBean();
			monitoreoCruzadoBean.setTotalesServiciosAlimentariosBean(totalesServiciosAlimentariosBean);
			monitoreoCruzadoBean.setTotalesLocalesBean(totalesLocalesBean);
			monitoreoCruzadoBean.setItemsServiciosAlimentariosBean(itemsServiciosAlimentariosBean);
			monitoreoCruzadoBean.setItemsLocalesBean(itemsLocalesBean);
			monitoreoCruzadoBean.setCalificacionNivelesServiciosAlimentarios(calificacionNivelesServiciosAlimentarios);
			monitoreoCruzadoBean.setCalificacionNivelesCocinaBean(calificacionNivelesCocinaBean);
			monitoreoCruzadoBean.setCalificacionNivelesAlmacenBean(calificacionNivelesAlmacenBean);
			monitoreoCruzadoBean.setCalificacionNivelesMedidasSeguridadBean(calificacionNivelesMedidasSeguridadBean);
			monitoreoCruzadoBean.setCalificacionNivelesDocumentacionYRegistrosBean(calificacionNivelesDocumentacionYRegistrosBean);
			monitoreoCruzadoBean.setCalificacionNivelesLocales(calificacionNivelesLocales);
			monitoreoCruzadoBean.setCalificacionNivelesMedidasSeguridadLocalBean(calificacionNivelesMedidasSeguridadLocalBean);
			monitoreoCruzadoBean.setCalificacionNivelesImplementosBasicosBean(calificacionNivelesImplementosBasicosBean);
			monitoreoCruzadoBean.setCalificacionNivelesInstrumentosDocumentacionRegistrosBean(calificacionNivelesInstrumentosDocumentacionRegistrosBean);
			monitoreoCruzadoBean.setCalificacionNivelesAparienciaActitudesConductaBean(calificacionNivelesAparienciaActitudesConductaBean);
			monitoreoCruzadoBean.setTituloReporte(construyeNombreCabecera());
			
			monitoreoCruzadoBean.setTotalComitesNacional(crossMonitoringDataService.obtenerTotalComiteGestion("000000"));
			monitoreoCruzadoBean.setTotalComitesFiltros(crossMonitoringDataService.obtenerTotalComiteGestion(getUbigeo()));
			monitoreoCruzadoBean.setTotalModulosNacional(crossMonitoringDataService.obtenerTotalModulos("000000"));
			monitoreoCruzadoBean.setTotalModulosFiltros(crossMonitoringDataService.obtenerTotalModulos(getUbigeo()));

			buildCrossMonitoringReport(monitoreoCruzadoBean);
		
			logBean = new LogBean(CunamasConstants.COD_REPORTE_CRUZADO, CunamasConstants.NOMBRE_REPORTE_CRUZADO, filtros.toString(), new Date(), new Short("1"),"");

		} catch (Exception e) {
			logBean = new LogBean(CunamasConstants.COD_REPORTE_MONITOREO, CunamasConstants.NOMBRE_REPORTE_MONITOREO, filtros.toString(), new Date(), new Short("0"),e.getMessage());

		}
		cunamasService.persistLog(logBean);

	}
	
	public String construyeNombreCabecera(){
		String tituloReporte = "";
		
		if("000000".equalsIgnoreCase(getUbigeo())){
			tituloReporte = "NACIONAL";
		}
		else
			if(!"00".equalsIgnoreCase(departamento)&&"00".equalsIgnoreCase(provincia)&&"00".equalsIgnoreCase(distrito)){
				tituloReporte = "DEPARTAMENTAL";
			}else
				if(!"00".equalsIgnoreCase(departamento)&&!"00".equalsIgnoreCase(provincia)&&"00".equalsIgnoreCase(distrito)){
					tituloReporte = "PROVINCIAL";
				}
				else
					if(!"00".equalsIgnoreCase(departamento)&&!"00".equalsIgnoreCase(provincia)&&!"00".equalsIgnoreCase(distrito)){
						tituloReporte = "DISTRITAL";	
					}
					else{
						tituloReporte = "COMITE DE GESTION";
					}
				
		tituloReporte += " - " + WebUtil.retornaTrimestre(trimestre.intValue()) + " TRIMESTRE " + anio;
		
		return tituloReporte;
	}

	private void buildCrossMonitoringReport(MonitoreoCruzadoBean monitoreoCruzadoBean) {
		try {

			if (totalesServiciosAlimentariosBean == null && totalesLocalesBean == null) {
				messageError = MessagesView.getI18nMessage("crossMonitoring.noResults");
				return;
			}

			String fileNameTemplate = CunamasConstants.DATA_LOAD_TEMPLATE_ROUTE
					+ CunamasConstants.CROSS_REPORT_TEMPLATE_NAME + ".xls";

			nameFile = CunamasConstants.CROSS_REPORT_TEMPLATE_NAME + "_" + anio
					+ "_" + trimestre;

			fileName = CunamasConstants.DATA_LOAD_OUTPUT_ROUTE + nameFile + "_"
					+ System.currentTimeMillis() + ".xls";

			ExcelReader excelReader = new ExcelReader();
			excelReader.readExcelFile(fileNameTemplate, fileName,monitoreoCruzadoBean);

			nameFilePDF = CunamasConstants.CROSS_REPORT_DETAIL_NAME + "_"
					+ anio + "_" + trimestre;

			fileNamePDF = CunamasConstants.DATA_LOAD_OUTPUT_ROUTE + nameFilePDF
					+ "_" + System.currentTimeMillis() + ".pdf";

			PDFUtil pdfUtil = new PDFUtil();
			pdfUtil.generatePdf(fileNamePDF, monitoreoCruzadoBean);

		} catch (Exception e) {
			e.printStackTrace();
			messageError = e.getMessage();
			fileName = null;
			fileNamePDF = null;
		}
	}
	
	private void getServiciosAlimentariosInputs(List<ServiciosAlimentariosBean> list) {
		if(list==null) return;
		
		totalesServiciosAlimentariosBean = crossMonitoringDataService.getTotalServiciosAlimentariosBean(list);
		itemsServiciosAlimentariosBean = crossMonitoringDataService.getItemsServiciosAlimentariosBean(list);
		
		calificacionNivelesServiciosAlimentarios = crossMonitoringDataService.obtenerCalificacionTabla(itemsServiciosAlimentariosBean,0);
		calificacionNivelesCocinaBean = crossMonitoringDataService.obtenerCalificacionTabla(itemsServiciosAlimentariosBean,1);
		calificacionNivelesAlmacenBean = crossMonitoringDataService.obtenerCalificacionTabla(itemsServiciosAlimentariosBean,2);
		calificacionNivelesMedidasSeguridadBean = crossMonitoringDataService.obtenerCalificacionTabla(itemsServiciosAlimentariosBean,3);
		calificacionNivelesDocumentacionYRegistrosBean = crossMonitoringDataService.obtenerCalificacionTabla(itemsServiciosAlimentariosBean,4);

		System.out.println("getServiciosAlimentariosInputs");
	}

	private void getLocalesInputs(List<LocalesBean> list) {
		if (list == null)
			return;

		totalesLocalesBean = crossMonitoringDataService.getTotalLocalesBean(list);
		itemsLocalesBean = crossMonitoringDataService.getItemsLocalesBean(list);

		calificacionNivelesLocales = crossMonitoringDataService.obtenerCalificacionTabla(itemsLocalesBean,0);
		calificacionNivelesMedidasSeguridadLocalBean = crossMonitoringDataService.obtenerCalificacionTabla(itemsLocalesBean,1);
		calificacionNivelesImplementosBasicosBean = crossMonitoringDataService.obtenerCalificacionTabla(itemsLocalesBean,2);
		calificacionNivelesInstrumentosDocumentacionRegistrosBean = crossMonitoringDataService.obtenerCalificacionTabla(itemsLocalesBean,3);
		calificacionNivelesAparienciaActitudesConductaBean = crossMonitoringDataService.obtenerCalificacionTabla(itemsLocalesBean,4);

		System.out.println("getLocalesInputs");
	}

	public String getUbigeo() {
		StringBuffer sb = new StringBuffer();
		return sb.append(departamento).append(provincia).append(distrito)
				.toString();
	}

	public String getOnload() {
		listaDep.clear();
		listaDis.clear();
		listaProv.clear();
		listaSede.clear();
		listaComite.clear();
		listaDep = cunamasService.retornaDepartamentos();
		return onload;
	}

	public void cargaComite() {
		listaComite.clear();
		if (distrito != "00") {
			String ubigeo = departamento + provincia + distrito;
			listaComite = cunamasService.retornaComite(ubigeo);
		} else {
			listaComite.clear();
		}
	}

	public void cargaProvincias() {
		listaProv.clear();
		listaDis.clear();
		listaSede.clear();
		if (!"00".equalsIgnoreCase(departamento)) {
			listaProv = cunamasService.retornaProvincia(departamento);
			listaSede = cunamasService.retornaSede(departamento);
		} else {
			listaDis.clear();
			listaProv.clear();
			listaSede.clear();
		}

	}

	public void cargaDistrito() {
		listaDis.clear();
		if (provincia != "00")
			listaDis = cunamasService.retornaDistrito(departamento + provincia);
		else {
			listaProv.clear();
		}
	}

	public void cargaSupervisor() {
		listaSupervisor.clear();
		if ("1".equalsIgnoreCase(formato.toString())) {
			listaSupervisor.add(new SelectItem(1, "Personal Sede Central"));
			listaSupervisor.add(new SelectItem(2, "Especialista Sede Zonal"));
			listaSupervisor.add(new SelectItem(3, "Coordinador de Campo"));
		} else {
			if ("2".equalsIgnoreCase(formato.toString())) {
				listaSupervisor.add(new SelectItem(4, "Asist. Administrativo"));
			}
		}
	}

	public String downloadFileExcel() {
		HttpServletResponse response = (HttpServletResponse) FacesContext
				.getCurrentInstance().getExternalContext().getResponse();
		response.setContentType("application/force-download");

		response.addHeader("Content-Disposition", "attachment; filename=\""
				+ nameFile + ".xls\"");
		byte[] buf = new byte[1024];

		try {
			File file = new File(fileName);
			long length = file.length();
			BufferedInputStream in = new BufferedInputStream(
					new FileInputStream(file));
			ServletOutputStream out = response.getOutputStream();
			response.setContentLength((int) length);
			while ((in != null) && ((length = in.read(buf)) != -1)) {
				out.write(buf, 0, (int) length);
			}
			in.close();
			out.flush();
			out.close();
		} catch (Exception exc) {
			exc.printStackTrace();
		}

		FacesContext.getCurrentInstance().responseComplete();
		return null;
	}

	public String downloadFilePdf() {
		HttpServletResponse response = (HttpServletResponse) FacesContext
				.getCurrentInstance().getExternalContext().getResponse();
		response.setContentType("application/force-download");

		response.addHeader("Content-Disposition", "attachment; filename=\""
				+ nameFilePDF + ".pdf\"");
		byte[] buf = new byte[1024];

		try {
			File file = new File(fileNamePDF);
			long length = file.length();
			BufferedInputStream in = new BufferedInputStream(
					new FileInputStream(file));
			ServletOutputStream out = response.getOutputStream();
			response.setContentLength((int) length);
			while ((in != null) && ((length = in.read(buf)) != -1)) {
				out.write(buf, 0, (int) length);
			}
			in.close();
			out.flush();
			out.close();
		} catch (Exception exc) {
			exc.printStackTrace();
		}

		FacesContext.getCurrentInstance().responseComplete();
		return null;
	}

	public void setOnload(String onload) {
		this.onload = onload;
	}

	public String getDepartamento() {
		return departamento;
	}

	public void setDepartamento(String departamento) {
		this.departamento = departamento;
	}

	public String getProvincia() {
		return provincia;
	}

	public void setProvincia(String provincia) {
		this.provincia = provincia;
	}

	public String getDistrito() {
		return distrito;
	}

	public void setDistrito(String distrito) {
		this.distrito = distrito;
	}

	public String getSede() {
		return sede;
	}

	public void setSede(String sede) {
		this.sede = sede;
	}

	public String getAnio() {
		return anio;
	}

	public void setAnio(String anio) {
		this.anio = anio;
	}

	public String getMes() {
		return mes;
	}

	public void setMes(String mes) {
		this.mes = mes;
	}

	public List<SelectItem> getListaProv() {
		return listaProv;
	}

	public void setListaProv(List<SelectItem> listaProv) {
		this.listaProv = listaProv;
	}

	public List<SelectItem> getListaDis() {
		return listaDis;
	}

	public void setListaDis(List<SelectItem> listaDis) {
		this.listaDis = listaDis;
	}

	public List<SelectItem> getListaDep() {
		return listaDep;
	}

	public void setListaDep(List<SelectItem> listaDep) {
		this.listaDep = listaDep;
	}

	public List<SelectItem> getListaSede() {
		return listaSede;
	}

	public void setListaSede(List<SelectItem> listaSede) {
		this.listaSede = listaSede;
	}

	public List<SelectItem> getListaComite() {
		return listaComite;
	}

	public void setListaComite(List<SelectItem> listaComite) {
		this.listaComite = listaComite;
	}

	public String getComite() {
		return comite;
	}

	public void setComite(String comite) {
		this.comite = comite;
	}

	public Long getTrimestre() {
		return trimestre;
	}

	public void setTrimestre(Long trimestre) {
		this.trimestre = trimestre;
	}

	public List<ServiciosAlimentariosBean> getServiciosAlimentariosBeans() {
		return serviciosAlimentariosBeans;
	}

	public void setServiciosAlimentariosBeans(
			List<ServiciosAlimentariosBean> serviciosAlimentariosBeans) {
		this.serviciosAlimentariosBeans = serviciosAlimentariosBeans;
	}

	public List<LocalesBean> getLocalesBeans() {
		return localesBeans;
	}

	public void setLocalesBeans(List<LocalesBean> localesBeans) {
		this.localesBeans = localesBeans;
	}

	public Long getFormato() {
		return formato;
	}

	public void setFormato(Long formato) {
		this.formato = formato;
	}

	public Long getSupervisor() {
		return supervisor;
	}

	public void setSupervisor(Long supervisor) {
		this.supervisor = supervisor;
	}

	public List<SelectItem> getListaSupervisor() {
		return listaSupervisor;
	}

	public void setListaSupervisor(List<SelectItem> listaSupervisor) {
		this.listaSupervisor = listaSupervisor;
	}

	public String getMessageError() {
		return messageError;
	}

	public void setMessageError(String messageError) {
		this.messageError = messageError;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public String getNameFile() {
		return nameFile;
	}

	public void setNameFile(String nameFile) {
		this.nameFile = nameFile;
	}

	public String getFileNamePDF() {
		return fileNamePDF;
	}

	public void setFileNamePDF(String fileNamePDF) {
		this.fileNamePDF = fileNamePDF;
	}

	public String getNameFilePDF() {
		return nameFilePDF;
	}

	public void setNameFilePDF(String nameFilePDF) {
		this.nameFilePDF = nameFilePDF;
	}
}